from twisted.internet import reactor, protocol
from twisted.protocols import basic
from twisted.internet import interfaces, reactor
import os
from PIL import Image
from time import time
from zope.interface import implements
from base64 import encodestring
import ImageUtil
import ServerUtil
from nodeinfo import Info

nodes = {}
class ContentProducer:
  implements(interfaces.IPushProducer)
  
  def __init__(self, protocol):
    self.protocol = protocol
    self.imgData = []
    self.path = 'C:\\Cars\\a.jpg'
    self.im = Image.open(self.path, 'r')
    self.startTime = None
    self.lineCount = 0
    self.dataRate = 0.0
    
  def pauseProducing(self):
    #print "ContentProducer paused"
    pass
    
  def resumeProducing(self):
    # get the image as a string data in array self.imgData
    self.imgData = ImageUtil.getImageDataInArray(self, str(self.im.tostring()))
    imLen = len(self.imgData)
    for i in range(0, imLen):
        # send the string image data to the client.
        self.protocol.transport.write(str(self.imgData[i])+"\r\n")
        self.lineCount += 1
        # if self.lineCount % 1000 == 0:
        if not self.startTime:
            self.startTime = time()
        if self.lineCount == 1000:
            print "rate = %.2f lines / second" % (self.lineCount / (time()-self.startTime))
            self.dataRate = str((self.lineCount / (time()-self.startTime)))
            self.lineCount = 0
            self.startTime = time()

  def stopProducing(self):
    pass

class ImageProtocol(basic.LineReceiver):
    def connectionMade(self):
        self.producer = ContentProducer(self)
        self.transport.registerProducer(self.producer, True)
        
    def lineReceived(self, line):
        if line.startswith('connectserver='):
            nodeparam = Info()
            self.setConnection(line[14:], nodeparam)
            print 'connection received from: ' + nodeparam.getName() + ', listening port: ' + nodeparam.getListenPort()
            if len(nodes) == 0:
                ServerUtil.addnode(nodes, nodeparam)
                print 'The new node has been added to the database'
                self.producer.resumeProducing()
            else:
                if nodes.has_key(nodeparam.getName()):
                    self.transport.write('servererrmsg=This name already exits please choose other name'+'\r\n')
                    self.transport.loseConnection()
                else:
                    ServerUtil.addnode(nodes, nodeparam)
                    print 'The new node has been added to the database'

            
        elif line.startswith('update'):
            pass
                    
    def connectionLost(self, connector):
        print 'connection lost from client' + 'a'
        

    def setConnection(self, param, nodeparam):
        nodeVal = param.split()
        nodeparam.setName(nodeVal[0])
        nodeparam.setListenPort(nodeVal[1])
        nodeparam.setUBandwidth(0.0)
        nodeparam.setDBandwidth(0.0)
    
class ImageServerFactory(protocol.ServerFactory):
    protocol = ImageProtocol


def normalize():
    pass
    
if __name__ == '__main__':
    port = 2000
    reactor.listenTCP(port, ImageServerFactory())
    reactor.run()
